home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / TUTOROOT.PAK / STEP11DV.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  10KB  |  432 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1994 by Borland International
  3. //   Tutorial application -- step11dv.cpp
  4. //----------------------------------------------------------------------------
  5. #include <owl/pch.h>
  6. #include <owl/dc.h>
  7. #include <owl/inputdia.h>
  8. #include <owl/chooseco.h>
  9. #include <owl/gdiobjec.h>
  10. #include <owl/docmanag.h>
  11. #include <owl/filedoc.h>
  12. #include <classlib/arrays.h>
  13. #include "step11dv.rc"
  14.  
  15. typedef TArray<TPoint> TPoints;
  16. typedef TArrayIterator<TPoint> TPointsIterator;
  17.  
  18. class TLine : public TPoints {
  19.   public:
  20.     // Constructor to allow construction from a color and a pen size.
  21.     // Also serves as default constructor.
  22.     TLine(const TColor& color = TColor(0), int penSize = 1) :
  23.       TPoints(10, 0, 10), PenSize(penSize), Color(color) {}
  24.  
  25.     // Functions to modify and query pen attributes.
  26.     int QueryPenSize() const
  27.     {
  28.       return PenSize;
  29.     }
  30.  
  31.     const TColor& QueryColor() const
  32.     {
  33.       return Color;
  34.     }
  35.  
  36.     void SetPen(const TColor& newColor, int penSize = 0);
  37.     void SetPen(int penSize);
  38.  
  39.     // TLine draws itself.  Returns true if everything went OK.
  40.     virtual bool Draw(TDC&) const;
  41.  
  42.     // The == operator must be defined for the container class, even if unused
  43.     bool operator ==(const TLine& other) const
  44.     {
  45.       return &other == this;
  46.     }
  47.  
  48.     friend ostream& operator <<(ostream& os, const TLine& line);
  49.     friend istream& operator >>(istream& is, TLine& line);
  50.  
  51.   protected:
  52.     int PenSize;
  53.     TColor Color;
  54. };
  55.  
  56. typedef TArray<TLine> TLines;
  57. typedef TArrayIterator<TLine> TLinesIterator;
  58.  
  59. class _USERCLASS TDrawDocument : public TFileDocument {
  60.   public:
  61.     TDrawDocument(TDocument* parent = 0) : TFileDocument(parent), Lines(0) {}
  62.    ~TDrawDocument()
  63.     {
  64.       delete Lines;
  65.     }
  66.  
  67.     // implement virtual methods of TDocument
  68.     bool   Open(int mode, const char far* path=0);
  69.     bool   Close();
  70.     bool   IsOpen()
  71.     {
  72.       return Lines != 0;
  73.     }
  74.     bool   Commit(bool force = false);
  75.     bool   Revert(bool clear = false);
  76.  
  77.     // data access functions
  78.     const TLine* GetLine(unsigned int index);
  79.     int    AddLine(TLine& line);
  80.  
  81.   protected:
  82.     TLines* Lines;
  83. };
  84.  
  85. class _USERCLASS TDrawView : public TWindowView {
  86.   public:
  87.     TDrawView(TDrawDocument& doc, TWindow* parent = 0);
  88.    ~TDrawView()
  89.     {
  90.       delete DragDC;
  91.       delete Line;
  92.     }
  93.  
  94.     static const char far* StaticName()
  95.     {
  96.       return "Draw View";
  97.     }
  98.  
  99.   protected:
  100.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  101.     TDC *DragDC;
  102.     TPen *Pen;
  103.     TLine *Line; // To hold a single line sent or received from document
  104.     void GetPenSize(); // GetPenSize always calls Line->SetPen().
  105.  
  106.     // Message response functions
  107.     void EvLButtonDown(uint, TPoint&);
  108.     void EvRButtonDown(uint, TPoint&);
  109.     void EvMouseMove(uint, TPoint&);
  110.     void EvLButtonUp(uint, TPoint&);
  111.     void Paint(TDC&, bool, TRect&);
  112.     void CmPenSize();
  113.     void CmPenColor();
  114.  
  115.     // Document notifications
  116.     bool VnCommit(bool force);
  117.     bool VnRevert(bool clear);
  118.  
  119.   DECLARE_RESPONSE_TABLE(TDrawView);
  120. };
  121.  
  122. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,   DrawTemplate);
  123. DrawTemplate drawTpl("Point Files (*.PTS)","*.pts",0,"PTS",dtAutoDelete|dtUpdateDir);
  124.  
  125. void
  126. TLine::SetPen(int penSize)
  127. {
  128.   if (penSize < 1)
  129.     PenSize = 1;
  130.   else
  131.     PenSize = penSize;
  132. }
  133.  
  134. void
  135. TLine::SetPen(const TColor& newColor, int penSize)
  136. {
  137.   // If penSize isn't the default (0), set PenSize to the new size.
  138.   if (penSize)
  139.     PenSize = penSize;
  140.  
  141.   Color = newColor;
  142. }
  143.  
  144. bool
  145. TLine::Draw(TDC& dc) const
  146. {
  147.   // Set pen for the dc to the values for this line
  148.   TPen pen(Color, PenSize);
  149.   dc.SelectObject(pen);
  150.  
  151.   // Iterates through the points in the line i.
  152.   TPointsIterator j(*this);
  153.   bool first = true;
  154.  
  155.   while (j) {
  156.     TPoint p = j++;
  157.  
  158.     if (!first)
  159.       dc.LineTo(p);
  160.     else {
  161.       dc.MoveTo(p);
  162.       first = false;
  163.     }
  164.   }
  165.   dc.RestorePen();
  166.   return true;
  167. }
  168.  
  169. ostream&
  170. operator <<(ostream& os, const TLine& line)
  171. {
  172.   // Write the number of points in the line
  173.   os << line.GetItemsInContainer();
  174.  
  175.   // Get and write pen attributes.
  176.   os << ' ' << line.Color << ' ' << line.PenSize;
  177.  
  178.   // Get an iterator for the array of points
  179.   TPointsIterator j(line);
  180.  
  181.   // While the iterator is valid (i.e. we haven't run out of points)
  182.   while(j)
  183.     // Write the point from the iterator and increment the array.
  184.     os << j++;
  185.   os << '\n';
  186.  
  187.   // return the stream object
  188.   return os;
  189. }
  190.  
  191. istream&
  192. operator >>(istream& is, TLine& line)
  193. {
  194.   unsigned numPoints;
  195.   is >> numPoints;
  196.  
  197.   COLORREF color;
  198.   int penSize;
  199.   is >> color >> penSize;
  200.   line.SetPen(TColor(color), penSize);
  201.  
  202.   while (numPoints--) {
  203.     TPoint point;
  204.     is >> point;
  205.     line.Add(point);
  206.   }
  207.  
  208.   // return the stream object
  209.   return is;
  210. }
  211.  
  212. bool
  213. TDrawDocument::Commit(bool force)
  214. {
  215.   if (!IsDirty() && !force)
  216.     return true;
  217.  
  218.   TOutStream* os = OutStream(ofWrite);
  219.   if (!os)
  220.     return false;
  221.  
  222.   // Write the number of lines in the figure
  223.   *os << Lines->GetItemsInContainer();
  224.  
  225.   // Append a description using a resource string
  226.   *os << ' ' << string(*GetDocManager().GetApplication(),IDS_FILEINFO) << '\n';
  227.  
  228.   // Get an iterator for the array of lines
  229.   TLinesIterator i(*Lines);
  230.  
  231.   // While the iterator is valid (i.e. we haven't run out of lines)
  232.   while (i) {
  233.     // Copy the current line from the iterator and increment the array.
  234.     *os << i++;
  235.   }
  236.   delete os;
  237.  
  238.   SetDirty(false);
  239.   return true;
  240. }
  241.  
  242. bool
  243. TDrawDocument::Revert(bool clear)
  244. {
  245.   if (!TFileDocument::Revert(clear))
  246.     return false;
  247.   if (!clear)
  248.     Open(0);
  249.   return true;
  250. }
  251.  
  252. bool
  253. TDrawDocument::Open(int /*mode*/, const char far* path)
  254. {
  255.   Lines = new TLines(5, 0, 5);
  256.   if (path)
  257.     SetDocPath(path);
  258.   if (GetDocPath()) {
  259.     TInStream* is = InStream(ofRead);
  260.     if (!is)
  261.       return false;
  262.  
  263.     unsigned numLines;
  264.     char fileinfo[100];
  265.     *is >> numLines;
  266.     is->getline(fileinfo, sizeof(fileinfo));
  267.     while (numLines--) {
  268.       TLine line;
  269.       *is >> line;
  270.       Lines->Add(line);
  271.     }
  272.     delete is;
  273.   }
  274.   SetDirty(false);
  275.   return true;
  276. }
  277.  
  278. bool
  279. TDrawDocument::Close()
  280. {
  281.   delete Lines;
  282.   Lines = 0;
  283.   return true;
  284. }
  285.  
  286. const TLine*
  287. TDrawDocument::GetLine(unsigned int index)
  288. {
  289.   if (!IsOpen() && !Open(ofRead | ofWrite))
  290.     return 0;
  291.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  292. }
  293.  
  294. int
  295. TDrawDocument::AddLine(TLine& line)
  296. {
  297.   int index = Lines->GetItemsInContainer();
  298.   Lines->Add(line);
  299.   SetDirty(true);
  300.   return index;
  301. }
  302.  
  303. DEFINE_RESPONSE_TABLE1(TDrawView, TWindowView)
  304.   EV_WM_LBUTTONDOWN,
  305.   EV_WM_RBUTTONDOWN,
  306.   EV_WM_MOUSEMOVE,
  307.   EV_WM_LBUTTONUP,
  308.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  309.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  310.   EV_VN_COMMIT,
  311.   EV_VN_REVERT,
  312. END_RESPONSE_TABLE;
  313.  
  314. TDrawView::TDrawView(TDrawDocument& doc,TWindow* parent) :
  315.   TWindowView(doc, parent), DrawDoc(&doc)
  316. {
  317.   DragDC  = 0;
  318.   Line    = new TLine(TColor::Black, 1);
  319.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW,0,1,0,0,0,0));
  320. }
  321.  
  322. void
  323. TDrawView::EvLButtonDown(uint, TPoint& point)
  324. {
  325.   if (!DragDC) {
  326.     SetCapture();
  327.     DragDC = new TClientDC(*this);
  328.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  329.     DragDC->SelectObject(*Pen);
  330.     DragDC->MoveTo(point);
  331.     Line->Add(point);
  332.   }
  333. }
  334.  
  335. void
  336. TDrawView::EvRButtonDown(uint, TPoint&)
  337. {
  338.   GetPenSize();
  339. }
  340.  
  341. void
  342. TDrawView::EvMouseMove(uint, TPoint& point)
  343. {
  344.   if (DragDC) {
  345.     DragDC->LineTo(point);
  346.     Line->Add(point);
  347.   }
  348. }
  349.  
  350. void
  351. TDrawView::EvLButtonUp(uint, TPoint&)
  352. {
  353.   if (DragDC) {
  354.     ReleaseCapture();
  355.     if (Line->GetItemsInContainer() > 1)
  356.       DrawDoc->AddLine(*Line);
  357.     Line->Flush();
  358.     delete DragDC;
  359.     delete Pen;
  360.     DragDC = 0;
  361.   }
  362. }
  363.  
  364. void
  365. TDrawView::CmPenSize()
  366. {
  367.   GetPenSize();
  368. }
  369.  
  370. void
  371. TDrawView::CmPenColor()
  372. {
  373.   TChooseColorDialog::TData colors;
  374.   static TColor custColors[16] =
  375.   {
  376.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  377.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  378.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  379.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  380.   };
  381.  
  382.   colors.Flags = CC_RGBINIT;
  383.   colors.Color = TColor(Line->QueryColor());
  384.   colors.CustColors = custColors;
  385.   if (TChooseColorDialog(this, colors).Execute() == IDOK)
  386.     Line->SetPen(colors.Color);
  387. }
  388.  
  389. void
  390. TDrawView::GetPenSize()
  391. {
  392.   char inputText[6];
  393.   int penSize = Line->QueryPenSize();
  394.  
  395.   wsprintf(inputText, "%d", penSize);
  396.   if (TInputDialog(this, "Line Thickness",
  397.                         "Input a new thickness:",
  398.                         inputText,
  399.                         sizeof(inputText),::Module).Execute() == IDOK) {
  400.     penSize = atoi(inputText);
  401.  
  402.     if (penSize < 1)
  403.       penSize = 1;
  404.   }
  405.   Line->SetPen(penSize);
  406. }
  407.  
  408. void
  409. TDrawView::Paint(TDC& dc, bool, TRect&)
  410. {
  411.   // Iterates through the array of line objects.
  412.   int i = 0;
  413.   const TLine* line;
  414.   while ((line = DrawDoc->GetLine(i++)) != 0)
  415.     line->Draw(dc);
  416. }
  417.  
  418. bool
  419. TDrawView::VnCommit(bool /*force*/)
  420. {
  421.   // nothing to do here, no data held in view
  422.   return true;
  423. }
  424.  
  425. bool
  426. TDrawView::VnRevert(bool /*clear*/)
  427. {
  428.   Invalidate();  // force full repaint
  429.   return true;
  430. }
  431.  
  432.